package com.woniu.common.api.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/*
 * 开启redis缓存，设置key的生产策略。主要用于注解情况下，默认使用方法的全限定名作为key    自动生成key
 */
@EnableCaching
@Configuration
public class RedisConfiguration extends CachingConfigurerSupport {
	/**
     * redisTemplate相关配置
     * @param factory
     * @return
     */
	@Bean
	@SuppressWarnings("all")
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
		RedisTemplate<String, Object> template  = new RedisTemplate<>();
		//设置工厂
		template.setConnectionFactory(factory);
		//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
//（默认使用JDK的序列化方式）
		Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
new Jackson2JsonRedisSerializer<>(Object.class);
		//创建对象映射
		ObjectMapper mapper = new ObjectMapper();
		//指定要序列化的域，field,get和set,以及修饰符范围，ANY是都有包括private和public
		mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		//指定序列化输入的类型，类必须是非final修饰的，final修饰的类，比如String,Integer
//等会抛出异常
		mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		//
		jackson2JsonRedisSerializer.setObjectMapper(mapper);
		//字符串序列化器
		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
		//key采用String的序列化方式
		template.setKeySerializer(stringRedisSerializer);
		//hash的key也采用String的方式
		template.setHashKeySerializer(stringRedisSerializer);
		//value采用jackson的方式
		template.setValueSerializer(jackson2JsonRedisSerializer);
		//hash的value也采用Jackson
		template.setHashValueSerializer(jackson2JsonRedisSerializer);
		
		template.afterPropertiesSet();
		return template;
	}
}